<template>
  <px-form ref="formRef" :model="formValue" :rules="rules" label-width="160px">
    <px-form-item label="厂区" prop="factoryId">
      <px-select v-model="formValue.factoryId" style="width: 100%" placeholder="请选择厂区名称" disabled>
        <px-option v-for="item in factoryList" :key="item.key" :label="item.label" :value="item.value" />
      </px-select>
    </px-form-item>
    <px-form-item label="科室" prop="className">
      <px-select v-model="formValue.className" disabled style="width: 100%" placeholder="请选择科室" filterable @change="classChanged">
        <px-option v-for="item in classNameList" :key="item.code" :label="item.name" :value="item.code" />
      </px-select>
    </px-form-item>
    <px-form-item label="报警点位" prop="point">
      <px-input v-model="formValue.point" disabled maxlength="100" placeholder="请输入报警点位" />
    </px-form-item>
    <px-form-item label="报警级别" prop="alarmLevel">
      <px-select v-model="formValue.alarmLevel" disabled style="width: 100%" placeholder="请选择报警级别" clearable>
        <px-option v-for="item in alarmLevelList" :key="item.key" :label="item.label" :value="item.value" />
      </px-select>
    </px-form-item>
    <px-form-item label="报警类型" prop="alarmType">
      <px-select v-model="formValue.alarmType" disabled style="width: 100%" placeholder="请选择报警类型" clearable>
        <px-option v-for="item in alarmTypeList" :key="item.key" :label="item.name" :value="item.value" />
      </px-select>
    </px-form-item>
    <px-form-item label="报警描述" prop="alarmDesc">
      <px-input v-model="formValue.alarmDesc" disabled type="textarea" placeholder="请输入报警描述" clearable />
    </px-form-item>
    <px-form-item label="所属系统" prop="systemId">
      <px-tree-select
        v-model="formValue.systemId"
        disabled
        clearable
        filterable
        :props="defaultProps"
        :data="filterSystemList"
        check-strictly
        node-key="code"
        style="width: 100%"
        placeholder="请选择设备系统（树状图）"
        @node-click="handleNodeClick"
      />
    </px-form-item>
    <px-form-item label="设备编号" prop="twinId">
      <px-input v-model="formValue.twinId" disabled placeholder="请点击选择" style="width: calc(100% - 108px); margin-right: 8px" />
      <px-button type="primary" plain style="width: 100px" disabled @click="dialogVisible = true">选择设备</px-button>
    </px-form-item>
    <px-form-item label="设备名称" prop="twinName">
      <px-input v-model="formValue.twinName" disabled placeholder="选择设备编号后自动带出" />
    </px-form-item>
    <px-form-item label="位置" prop="twinPositionDesc">
      <px-input v-model="formValue.twinPositionDesc" disabled placeholder="选择设备编号后自动带出" />
    </px-form-item>
    <px-form-item label="是否纳入报警统计分析" prop="countPointFlag">
      <px-select v-model="formValue.countPointFlag" disabled style="width: 100%" placeholder="请选择是否纳入报警统计分析">
        <px-option key="1" label="是" value="Y" />
        <px-option key="2" label="否" value="N" />
      </px-select>
    </px-form-item>
  </px-form>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, nextTick, watchEffect } from "vue";

import type { FormValueType } from "@/api/alarm";
import { querySystemSelect } from "@/api/equip/archive";
import { queryDictData, querySystemTree } from "@/api/common";
import { getAlarmPointInfo } from "@/api/alarm";

import type { PropsTypeForEdit, OptionsType } from "../type";

const classNameList = JSON.parse(localStorage.getItem("classList"));

const defaultProps = {
  children: "children",
  label: "name",
  value: "code"
};

const factoryList = [
  {
    label: "创新中心一期",
    value: "FAC_83abf9",
    key: "FAC_83abf9"
  },
  {
    label: "创新中心二期",
    value: "FAC_93abf6",
    key: "FAC_93abf6"
  }
];

const formRef = ref(null);
const dialogVisible = ref(false);
const formValue = ref<FormValueType>({
  id: 0,
  factoryId: "",
  factoryName: "",
  className: "",
  classNameDesc: "",
  point: "",
  alarmLevel: "",
  alarmType: "",
  alarmDesc: "",
  systemId: "",
  systemName: "",
  twinId: "",
  twinName: "",
  twinPosition: "",
  twinPositionDesc: "",
  countPointFlag: "N"
});
const rules = reactive({
  alarmLevel: [{ required: true, message: "请选择报警级别", trigger: "blur" }],
  alarmType: [{ required: true, message: "请选择报警类型", trigger: "blur" }],
  alarmDesc: [{ required: true, message: "请输入报警描述", trigger: "blur" }]
});
const alarmTypeList = ref([]);
const alarmLevelList = ref<OptionsType>([]);
const allSystemList = ref<any[]>([]);
const systemIdList = ref<string[]>([]);
const systemListForCondition = ref<any[]>([]);

const props = defineProps<PropsTypeForEdit>();

if (classNameList.length === 1) {
  formValue.value.className = classNameList[0].code;
}

const filterSystemList = computed<any[]>(() => {
  if (allSystemList.value?.length > 0) return allSystemList.value;
  return systemListForCondition.value;
});

const isAllSystemTreeItemType = (node: any) => {
  return "type" in node;
};

const getCodes = (node): string[] => {
  const codes = [node.code];
  if (node?.children?.length) {
    node.children.forEach(item => {
      codes.push(...getCodes(item));
    });
  }
  return codes;
};

const getNodeForSecondLevel = node => {
  let parentNode = node.parent;
  let parentNodeType = parentNode.data.type;

  while (parentNode && parentNodeType && parentNodeType !== "className") {
    parentNode = parentNode?.parent;
    parentNodeType = parentNode?.data?.type;
  }

  return parentNode;
};

// 点击左侧树节点，获取工厂、科室、系统、系统codes
const handleNodeClick = async (node, nodeData) => {
  if (isAllSystemTreeItemType(node)) {
    if (node.type === "className") {
      // 二级科室
      formValue.value.className = node.code;
      await nextTick();
      formValue.value.systemId = "";
      formValue.value.systemName = "";
    } else if (node.type === "systemCategory") {
      // 三级及三级以下节点
      systemIdList.value = getCodes(node);
      formValue.value.systemName = node.name;
      const nodeForSecondLevel = getNodeForSecondLevel(nodeData);
      formValue.value.className = nodeForSecondLevel.data.code;
    }
  } else {
    formValue.value.systemName = node.name;
    systemIdList.value = getCodes(node);
  }
};

const getAllSystemTree = async () => {
  try {
    const res = await querySystemSelect({ className: formValue.value.className });
    if ((res as any[]).length) {
      allSystemList.value = res as any[];
      systemListForCondition.value = [];
    }
  } catch (err) {
    console.log("queryAllSystemTree error", err);
  }
};

const getSystemTreeByCondition = async () => {
  try {
    const res = await querySystemTree({ className: formValue.value.className });
    if ((res as any[]).length) {
      systemListForCondition.value = res as any[];
      allSystemList.value = [];
    }
  } catch (err) {
    console.log("querySystemTree error", err);
  }
};

const classChanged = () => {
  if (formValue.value.systemId) {
    formValue.value.systemId = "";
    formValue.value.systemName = "";
  }
  formValue.value.twinId = "";
  formValue.value.twinName = "";
  formValue.value.twinPosition = "";
  formValue.value.twinPositionDesc = "";
  formValue.value.alarmType = "";
  getAlarmTypeList();
};

watchEffect(() => {
  if (formValue.value.className) {
    getSystemTreeByCondition();
  } else {
    getAllSystemTree();
  }
});

const getAlarmLevelList = async () => {
  const res = await queryDictData({ typeCode: "ALARM_LEVEL" });
  if (res?.length) {
    alarmLevelList.value = res.map(item => {
      return {
        label: item.name,
        value: item.value,
        key: item.id
      };
    });
  }
};

const getAlarmTypeList = async () => {
  if (formValue.value.className) {
    alarmTypeList.value = await queryDictData({ typeCode: `${formValue.value.className}_ALARM_TYPE` });
  } else {
    classNameList?.forEach(async item => {
      const res = await queryDictData({ typeCode: `${item.code}_ALARM_TYPE` });
      if (res) {
        alarmTypeList.value = alarmTypeList.value.concat(res);
      }
      alarmTypeList.value = alarmTypeList.value?.filter((obj, index, self) => {
        return self.map(x => x.value).indexOf(obj.value) === index;
      });
    });
  }
};

const getInfo = async () => {
  const res = await getAlarmPointInfo({ point: props.point });
  Object.keys(formValue.value).forEach(key => {
    formValue.value[key] = res[key];
  });
  getAlarmTypeList();
};

if (props.point) {
  getInfo();
}

const init = () => {
  getAlarmLevelList();
};

init();
</script>
